package edu.pku.sei.sct.primitives;

import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EReference;

import edu.pku.sei.AMT.LinkConstraint;
import edu.pku.sei.ocl.evaluation.Context;
import edu.pku.sei.ocl.evaluation.Environment;
import edu.pku.sei.sct.evaluation.SCTEnvironment;

public class RemoveLink extends AbstractPrimitive {
	public static final String ID = "RemoveLink";
	
	public RemoveLink(SCTEnvironment e) {
		super(e);
		// TODO Auto-generated constructor stub
	}

	/*
	 * argv[0] = linkConstraint
	 * argv[1] = Context
	 */
	@SuppressWarnings({ "rawtypes", "unchecked" })
	@Override
	public Object execute(Object... argv) {
		System.out.println("remove link");
		
		LinkConstraint v = (LinkConstraint) argv[0];
		Context context = (Context) argv[1];
		boolean check = false;
		
		if(argv.length>2)
			check = (boolean)argv[2];
		
		EObject so = (EObject) context.getValue(v.getSource().getName());
		EObject to = (EObject) context.getValue(v.getTarget().getName());
		
		EReference ref = this.getSctEnvironment().getReference(v.getSource().getScope(), v.getSource().getType(), v.getRefName());
		if(check && Environment.log.oclIsNew(so, to, ref))
			return false;
		
		if(ref.isMany()) {
			EList list = (EList)so.eGet(ref);
			list.remove(to);
			this.getSctEnvironment().manager.removeLink(ref, so, to);
			Environment.log.delete(so, to, ref);
		} else {
			if(so.eGet(ref)==to){
				so.eSet(ref, null);
				this.getSctEnvironment().manager.removeLink(ref, so, to);
				Environment.log.delete(so, to, ref);
			}
		}
		
		
		
		return true;
	}

	@Override
	public String getID() {
		return ID;
	}

}
